/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.demo.sshd;

import com.google.common.collect.ImmutableMap;
import org.apache.sshd.SshServer;
import org.apache.sshd.common.util.OsUtils;
import org.apache.sshd.server.PasswordAuthenticator;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.apache.sshd.server.session.ServerSession;
import org.apache.sshd.server.shell.ProcessShellFactory;

import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.util.EnumSet;
import java.util.Properties;
import java.util.regex.Pattern;

/**
 * @author vacoor
 */
public class Sshd {
    private static final String WELCOME = "Welcome to my server";
    public static final String SSHD_PORT = "sshd.port";
    public static final String SSHD_ROOT_DIR = "sshd.root.dir";
    public static final String SSHD_HOME_DIR = "sshd.home.dir";

    public static boolean isUnused(String host, int port) {
        try {
            InetAddress addr = InetAddress.getByName(host);
            new Socket(addr, port).close();
        } catch (IOException e) {
            return true;
        }
        return false;
    }

    public static void main(String[] args) throws IOException {
        SshServer sshServer = SshServer.setUpDefaultServer();
//        SshServer sshServer = new SshServer();
        sshServer.setPort(2222);
        sshServer.setProperties(
                ImmutableMap.<String, String>of(
                        SshServer.WELCOME_BANNER, "Whel"
                )
        );
        sshServer.setKeyPairProvider(new SimpleGeneratorHostKeyProvider("key.ser"));
        sshServer.setPasswordAuthenticator(new PasswordAuthenticator() {
            public boolean authenticate(String username, String password, ServerSession session) {
                return username != null && username.equals(password);
            }
        });
//        sshServer.start();
        Properties props = new Properties();
        props.put(SSHD_PORT, "2222");
        props.put(SSHD_ROOT_DIR, "/");
        props.put("TERM", "xterm-color");

        createStub(props).start();
    }

    public static SshServer createStub(Properties props) throws IOException {
        int _port = Integer.parseInt(props.getProperty(SSHD_PORT, "2222"));

        File rootDir = new File(props.getProperty(SSHD_ROOT_DIR, "workDir"));
        String homeDir = props.getProperty(SSHD_HOME_DIR, "/");
        String physycalHomeDir = new File(rootDir.getAbsolutePath() + homeDir).getAbsolutePath();
        physycalHomeDir = physycalHomeDir.replaceAll(Pattern.quote("\\"), "/");
        physycalHomeDir = physycalHomeDir.replaceAll("/+", "/");
        physycalHomeDir = physycalHomeDir.replaceAll("/", "\\\\");
        rootDir.mkdirs();

        SshServer _sshd = SshServer.setUpDefaultServer();
        _sshd.setPort(_port);
        _sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider("key.ser"));

        _sshd.setPasswordAuthenticator(new PasswordAuthenticator() {
            public boolean authenticate(String username, String password, ServerSession session) {
                return username != null && username.equals(password);
            }
        });

        _sshd.getProperties().put(SshServer.WELCOME_BANNER, WELCOME);
        // _sshd.getProperties().put(SshServer.AUTH_METHODS, "publickey");
        // _sshd.setSessionFactory(new JenkinsSessionFactory());
        //sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystem.Factory()));
        // _sshd.setFileSystemFactory(new JenkinsFileSystemFactory(props.getProperty(SSHD_ROOT_DIR)));
        // _sshd.setCommandFactory(new JenkinsCommandFactory());
        // _sshd.setShellFactory(new ProcessShellFactory(new String[] {props.getProperty("shell.cmd", "cmd.exe"), "/K", "cd /d "+physycalHomeDir+""}, EnumSet.of(ProcessShellFactory.TtyOptions.Echo, ProcessShellFactory.TtyOptions.ICrNl, ProcessShellFactory.TtyOptions.ONlCr)));
        SshServer sshServer = new SshServer();

        if (OsUtils.isUNIX()) {
            _sshd.setShellFactory(new ProcessShellFactory(new String[]{"/bin/sh", "-i", "-l"},
                    EnumSet.of(ProcessShellFactory.TtyOptions.ONlCr)));
        } else {
            _sshd.setShellFactory(new ProcessShellFactory(new String[]{"cmd.exe "},
                    EnumSet.of(ProcessShellFactory.TtyOptions.Echo, ProcessShellFactory.TtyOptions.ICrNl, ProcessShellFactory.TtyOptions.ONlCr)));
        }
        /*
        _sshd.setCommandFactory(new ScpCommandFactory(new CommandFactory() {
            public Command createCommand(String command) {
                EnumSet<ProcessShellFactory.TtyOptions> ttyOptions;
                if (OsUtils.isUNIX()) {
                    ttyOptions = EnumSet.of(ProcessShellFactory.TtyOptions.ONlCr);
                } else {
                    ttyOptions = EnumSet.of(ProcessShellFactory.TtyOptions.Echo, ProcessShellFactory.TtyOptions.ICrNl, ProcessShellFactory.TtyOptions.ONlCr);
                }
                return new ProcessShellFactory(command.split(" "), ttyOptions).create();
            }
        }));
        */
        //sshd.setIoServiceFactoryFactory(new MinaServiceFactoryFactory());
        //sshd.setIoServiceFactoryFactory(new Nio2ServiceFactoryFactory());
        return _sshd;

    }
}
